/*-------------------------------------------------------------------------
 *
 * gramparse.h
 *		“原始”解析器的共享定义（仅限flex和bison阶段）
 *
 * 注意：此文件仅用于核心解析文件中，即，parser.c，gram.y，scan.l和src/common/keywords.c。
 * 需要在核心解析器之外的定义应在parser.h中。
 *
 *
 * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * src/include/parser/gramparse.h
 *
 *-------------------------------------------------------------------------
 */

#ifndef GRAMPARSE_H
#define GRAMPARSE_H

#include "nodes/parsenodes.h"
#include "parser/scanner.h"

/*
 * 注意：只在包含 scanner.h 之后再包含 gram.h，
 * 因为 scanner.h 定义了 YYLTYPE。
 */
#include "parser/gram.h"

/*
 * flex 扫描器允许我们传递的 YY_EXTRA 数据。原始解析/词法分析所需的私有状态在这里。
 */
typedef struct base_yy_extra_type
{
	/*
	 * 核心扫描器使用的字段。
	 */
	core_yy_extra_type core_yy_extra;

	/*
	 * base_yylex() 的状态变量。
	 */
	bool		have_lookahead; /* 是lookahead信息有效吗? */
	int			lookahead_token;	/* 一-token lookahead */
	core_YYSTYPE lookahead_yylval;	/* yylval用于lookahead token */
	YYLTYPE		lookahead_yylloc;	/* yylloc用于lookahead token */
	char	   *lookahead_end;	/* 当前标记的结束 */
	char		lookahead_hold_char;	/* 要放回 *lookahead_end */

	/*
	 * 属于语法的状态变量。
	 */
	List	   *parsetree;		/* 最终解析结果在这里交付 */
} base_yy_extra_type;

/*
 * 从原则上讲，我们应该使用 yyget_extra() 从 yyscanner 结构中获取 yyextra 字段。
 * 然而，flex 始终将该字段放在首位，这在性能上足够关键，
 * 使得使用内联宏作弊似乎是值得的。
 */
#define pg_yyget_extra(yyscanner) (*((base_yy_extra_type **) (yyscanner)))


/* 来自 parser.c */
extern int	base_yylex(YYSTYPE *lvalp, YYLTYPE *llocp,
					   core_yyscan_t yyscanner);

/* 来自 gram.y */
extern void parser_init(base_yy_extra_type *yyext);
extern int	base_yyparse(core_yyscan_t yyscanner);

#endif							/* GRAMPARSE_H */
